﻿using AutoMapper.Features;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Wq.CaseService.Entities;
using Wq.CaseService.Models;
using Wq.Extensions.Common;
using Wq.Extensions.Repository;
using Wq.Model;

namespace Wq.CaseService
{
    /// <summary>
    /// 实列
    /// </summary>
    public class ExampleService : SqlSugarBaseRepository<ExampleInfo>, IAddSingleton
    {
        /// <summary>
        /// 转实体
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private ExampleInfo EditToModel(ExampleEdit info)
        {
            var model = info.Map<ExampleInfo>();
            if (info.FeaturesIds?.Count > 0)
                model.Features = info.FeaturesIds.Select(p => new ExampleFeaturesInfo { Id = 0, FeaturesId = p, ExampleId = 0 }).ToList();
            if (info.Images?.Count > 0)
                model.Thumbnails = info.Images.Select(p => new ExampleThumbnailInfo { Id = 0, FilePath = p, ExampleId = 0 }).ToList();
            return model;
        }

        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="model"></param>
        /// <exception cref="MyException"></exception>
        private void Verify(ExampleEdit model)
        {
            if(string.IsNullOrEmpty(model.Name))
                throw new MyException("案例名称不能为空");
            if (string.IsNullOrEmpty(model.Sponsor))
                throw new MyException("主办方不能为空");
            if(model.IndustryId == 0)
                throw new MyException("行业不能为空");
            if(model.CategoryId == 0)
                throw new MyException("分类不能为空");

                
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="info"></param>
        public void Create(ExampleEdit info)
        {
            Verify(info);
            var model = EditToModel(info);
            model.CreateTime = DateTime.Now;
            Context.InsertNav(model)
                .Include(p => p.Process)
                .Include(p => p.Thumbnails)
                .Include(p => p.Features).ExecuteCommand();
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="info"></param>
        public void Save(ExampleEdit info)
        {
            Verify(info);
            var lod = base.GetById(info.Id);
            var model = EditToModel(info);
            model.CreateTime = lod.CreateTime;
            model.Visits = lod.Visits;
            Context.UpdateNav(model) //.IgnoreColumns(it => new { it.CreateTime, it.Visits })
            .Include(p => p.Process)
            .Include(p => p.Thumbnails)
            .Include(p => p.Features).ExecuteCommand();
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        public void Delete(long id) =>
            Context.DeleteNav<ExampleInfo>(p => p.Id == id)
                .Include(p => p.Process)
                .Include(p => p.Features)
                .ExecuteCommand();
        

        /// <summary>
        /// 获取实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ExampleInfo Details(long id) =>
            Context.Queryable<ExampleInfo>()
            .Where(p => p.Id == id)
            .Includes(p => p.Process)
            .Includes(p => p.Features)
            .Includes(p => p.Thumbnails)
            .First();

        /// <summary>
        /// 修改排序
        /// </summary>
        /// <param name="id"></param>
        /// <param name="sequence"></param>
        public void UpdateSequence(long id, long sequence) => Context.Updateable<ExampleInfo>().SetColumns(p => p.Sequence == sequence).Where(p => p.Id == id).ExecuteCommand();

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="pageModel"></param>
        /// <returns></returns>
        public List<ExampleView> List(PageModel<ExampleQuery> pageModel)
        {
            int count = 0;
            var list = Context.Queryable<ExampleInfo, CategoryInfo, IndustryInfo, AdviserInfo>((e,c,i,a) => new JoinQueryInfos(
                 JoinType.Left, e.CategoryId == c.Id,
                 JoinType.Left, e.IndustryId == i.Id,
                 JoinType.Left, e.AdviserId == a.Id
                ))
               .WhereIF(!string.IsNullOrEmpty(pageModel.Entity.Name),(e, c, i, a) => e.Name.Contains(pageModel.Entity.Name))
               .WhereIF(!string.IsNullOrEmpty(pageModel.Entity.Sponsor), (e, c, i, a) => e.Sponsor.Contains(pageModel.Entity.Sponsor))
               .WhereIF(pageModel.Entity.IndustryId.HasValue && pageModel.Entity.IndustryId > 0, (e, c, i, a) => e.IndustryId == pageModel.Entity.IndustryId)
               .WhereIF(pageModel.Entity.CategoryId.HasValue && pageModel.Entity.CategoryId > 0, (e, c, i, a) => e.CategoryId == pageModel.Entity.CategoryId)
               .WhereIF(pageModel.Entity.AdviserId.HasValue && pageModel.Entity.AdviserId > 0, (e, c, i, a) => e.AdviserId == pageModel.Entity.AdviserId)
               .WhereIF(pageModel.BeginDateTime.HasValue, (e, c, i, a) => e.CreateTime >= pageModel.BeginDateTime)
               .WhereIF(pageModel.EndDateTime.HasValue, (e, c, i, a) => e.EndDate <= pageModel.EndDateTime)
               .Select((e, c, i, a) => new ExampleView { 
                   Id = e.Id,
                   Name = e.Name,
                 //  Tag = e.Tag,
                  // Sponsor = e.Sponsor,
                  // Thumbnail = e.Thumbnail,
                   IndustryName = i.Name,
                   CategoryName = c.Name,
                   AdviserName = a.Name,
                 //  StartDate = e.StartDate,
                 //  EndDate = e.EndDate,
                   CreateTime = e.CreateTime,
                 //  Visits = e.Visits
               },true)
                .Mapper(p => {
                })
                .ToPageList(pageModel.Page.Index, pageModel.Page.Size, ref count);
                pageModel.Page.Num = count;
                return list;
        }

        /// <summary>
        /// 查询前多少条案例
        /// </summary>
        /// <param name="CategoryId"></param>
        /// <param name="top"></param>
        /// <returns></returns>
        public List<ExampleBaseView> ExampleByCategoryId(long CategoryId, int top)
        {
            var list = Context.Queryable<ExampleInfo, CategoryInfo>((e, c) => new JoinQueryInfos(
                               JoinType.Left, e.CategoryId == c.Id
                                              ))
                .WhereIF(CategoryId > 0 ,(e, c) => e.CategoryId == CategoryId)
                .OrderBy((e, c) => e.Sequence)
                .Select((e, c) => new ExampleBaseView
                {
                    Id = e.Id,
                    Name = e.Name,
                    Thumbnail = e.Thumbnail,
                    CategoryName = c.Name
                })
                .Take(top)
                .ToList();
            var ids = list.Select(p => p.Id).ToList();
            var thumbnais = Context.Queryable<ExampleThumbnailInfo>().Where(p => ids.Contains(p.ExampleId)).ToList();
            list.ForEach(p =>
            {
                p.Thumbnail = thumbnais.Where(f => f.ExampleId == p.Id).FirstOrDefault()?.FilePath;
            });
            return list;
        }
    }
}
